#!/usr/bin/env python

import utiles
import servers
import MySQLdb
import MySQLdb.cursors
import string
from decimal import Decimal
import sys
import os

host=servers.host
user=servers.user
passwd=servers.passwd
db_name=servers.db_name

miBD=MySQLdb.connect(host=host,user=user,passwd=passwd,db=db_name)
miCursor=miBD.cursor()
miBDDict=MySQLdb.connect(host=host,user=user,passwd=passwd,db=db_name, cursorclass=MySQLdb.cursors.DictCursor)
miCursorDict=miBDDict.cursor()
midb=MySQLdb.connect(host=host,user=user,passwd=passwd,db=db_name)
micursor=midb.cursor()

lineaGuiones = "-"*101
lineaRenglon = "%8s %-34s %13s %13s %13s %13s"

def crearTabla():
    sql = " CREATE TABLE `erpsussan`.`vtas_detalle` (`id` INT( 5 ) NOT NULL AUTO_INCREMENT ,\
    `idcliente` VARCHAR( 15 ) NOT NULL ,`fecha` DATE NOT NULL ,`detalle1` VARCHAR( 35 ) NOT NULL ,\
    `detalle2` VARCHAR( 12 ) NOT NULL ,`debe` DECIMAL( 10, 2 ) NOT NULL ,`haber` DECIMAL( 10, 2 ) NOT NULL ,\
    PRIMARY KEY ( `id` )) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_spanish_ci"
    try:
        crear = ordenCruda(sql)
        print "Tabla vtas_detalle creada.",
    except:
        sql = "TRUNCATE TABLE vtas_detalle"
        crear = ordenCruda(sql)
        print "La tabla vtas_detalle ya existe. Datos eliminados."

def executa(sql):
    micursor.execute(sql)
    ultimoid = midb.insert_id()
    micursor.execute("set autocommit = 1")
    return ultimoid

def ordenCruda(consultaSQL):
    miCursor.execute(consultaSQL)
    auxiliar = miCursor.fetchall()
    return auxiliar

def ordenCrudaDict(consultaSQL, previo="SELECT 1"):
    miCursorDict.execute(previo)
    print consultaSQL
    miCursorDict.execute(consultaSQL)
    auxiliar = miCursorDict.fetchall()    
    return auxiliar

def espacios(nrofactura,rellenar):
    aux = ""
    nrofactura = str(nrofactura)
    for i in range(rellenar-len(nrofactura)):
        aux += " "
    return aux+nrofactura

def invertirFecha(fecha):
    fecha = str(fecha)
    return fecha[8:10]+"-"+fecha[5:7]+"-"+fecha[2:4]

def procesaArchivos():
    #Se procesa la tabla vtas_valores2 agregando la columna correspondiente a los recibos
    #Se crea si no existe, si existe se eliminan los datos. Cualquiera sea el caso, se actualiza con datos frescos.
    os.system("cls")
    import vtas_valores2
    vtas_valores2.crearTabla()
    vtas_valores2.llenarTabla()
    #Fin del tratamiento de vtas_valores2
    print
    
    #Se procesa la tabla saldos2, actualizando los registros en la misma
    #Se crea si no existe, si existe se eliminan los datos. Cualquiera sea el caso, se actualiza con datos frescos.
    import saldos2
    saldos2.crearTabla()
    saldos2.llenarTabla()
    #Fin del tratamiento de vtas_valores2
    print

# *****************************************************************************

def grabaDetalle(idcliente,fecha,detalle1,detalle2,debe,haber):
    sql1 = "INSERT INTO vtas_detalle(idcliente,fecha,detalle1,detalle2,debe,haber) "
    sql2 = "VALUES ('%s','%s','%s','%s','%s','%s')" % (idcliente,fecha,detalle1,detalle2,debe,haber)
    sql = sql1 + sql2
    resultado = executa(sql)

def listaClientes():
    sql = "SELECT idcliente,nombre,telefono FROM cliente"
    listaClientes = ordenCruda(sql)
    if listaClientes == (): listaClientes = None
    return listaClientes

def datosCliente(idcliente):
    sql = "SELECT nombre,telefono FROM cliente WHERE idcliente = '%s'" % (idcliente)
    datos = ordenCruda(sql)
    if datos != ():
        datos = (datos[0][0], datos[0][1])
    else:
        datos = None
    return datos

def saldoMigracion(idcliente,nombre,telefono,totales):
    sql = "SELECT saldoinicial FROM saldos WHERE idcliente = '%s' AND saldoinicial<>'0.00'" % (idcliente)
    saldoInicial = ordenCruda(sql)
    encabezado = True

    if saldoInicial == (): return (encabezado,totales)

    saldoInicial = saldoInicial[0][0]
    printEncabezado(idcliente,nombre,telefono)
    encabezado = False
    if saldoInicial >= Decimal("0.00"):
        totales[0] += Decimal(str(saldoInicial)) #debe
        aux1 = "%12s" % ("%12.2f" % (totales[0]))
        aux2 = "0.00"
    else:
        totales[1] += abs(Decimal(str(saldoInicial))) #haber
        aux1 = "0.00"
        aux2 = "%12s" % ("%12.2f" % (totales[1]))

    totales[2] = totales[0] - totales[1] #saldo
    
    #print lineaRenglon % ("12-05-08","Saldo migracion","",aux1,aux2,totales[2])
    grabaDetalle(idcliente,"2008-05-12","Saldo migracion","",totales[0],totales[1])

    sql = "SELECT * FROM saldos WHERE idcliente = '%s' AND saldoinicial='0.00'" % (idcliente)
    listaSaldo = ordenCrudaDict(sql)
    if listaSaldo != ():
        for pago in listaSaldo:
            descripcion = ("Pago saldo migracion R "+str(pago['idrecibo']))[0:33]
            montoPagado = Decimal(str(pago['montopagado']))
            totales[1] += montoPagado
            totales[2] = totales[0] - totales[1] #saldo
            aux1 = "%12s" % ("%12.2f" % (montoPagado))
            aux2 = "%12s" % ("%12.2f" % (totales[2]))
            #print lineaRenglon % (invertirFecha(pago['fecha']),descripcion,"","",aux1,aux2)
            grabaDetalle(idcliente,pago['fecha'],descripcion,"",Decimal("0.00"),montoPagado)
    #print

    return (encabezado,totales)

def ventas(idcliente):
    sql = "SELECT * FROM ventas WHERE idcliente = '%s' AND totalfactura>0 ORDER BY fecha" % (idcliente)
    listaVentas = ordenCrudaDict(sql)
    if listaVentas == (): listaVentas = None
    return listaVentas

def ventasTienePagos(idventa):
    sql = "SELECT * FROM ventastienepagos WHERE idventa = '%s'" % (idventa)
    listaVentasTienePagos = ordenCrudaDict(sql)
    if listaVentasTienePagos == (): listaVentasTienePagos = None
    return listaVentasTienePagos

def vtas_CtasCtes(idventa):
    sql = "SELECT * FROM vtas_ctasctes WHERE idventa = '%s' AND montocuota>0 ORDER BY vencimiento" % (idventa)
    listaVtasCtasCtes = ordenCrudaDict(sql)
    if listaVtasCtasCtes == (): listaVtasCtasCtes = None
    return listaVtasCtasCtes

def vtas_CtasCtesTienePagos(idventa):
    sql = "SELECT * FROM vtas_ctasctestienepagos WHERE idventa = '%s' AND montopagado>0 ORDER BY fecha" % (idventa)
    listaVtasCtasCtes = ordenCrudaDict(sql)
    if listaVtasCtasCtes == (): listaVtasCtasCtes = None
    return listaVtasCtasCtes

def creandoListaRecibos(idventa):
    sql = "SELECT idrecibo FROM vtas_ctasctestienepagos WHERE idventa = '%s' GROUP BY idrecibo ORDER BY fecha" % (idventa)
    listaRecibo = ordenCruda(sql)
    if listaRecibo == (): 
        listaRecibo = None
    else:
        lisRec = []
        for recibo in listaRecibo:
            lisRec.append(recibo[0])
        listaRecibo = lisRec
    return listaRecibo
    
def vtas_NC(idventa):
    sql = "SELECT * FROM vtas_nc WHERE idventa = '%s' ORDER BY fecha" % (idventa)
    listaNC = ordenCrudaDict(sql)
    if listaNC == (): listaNC = None
    return listaNC

def vtas_Valores(idrecibo):
    sql = "SELECT * FROM vtas_valores WHERE idrecibo = '%s' ORDER BY fecha" % (idrecibo)
    listaRecibo = ordenCrudaDict(sql)
    if listaRecibo == (): listaRecibo = None
    return listaRecibo

def vtas_ValoresxCliente(idcliente):
    sql1 = "SELECT * FROM vtas_valores WHERE idcliente = '%s'" % (idcliente)
    sql2 = " AND descripcion NOT LIKE '%saldo inicial%' "
    sql = sql1 + sql2
    listaRecibo = ordenCrudaDict(sql)
    if listaRecibo == (): listaRecibo = None
    return listaRecibo

def printEncabezado(idcliente,nombre,telefono):
    print
    print idcliente,nombre,"Telf.: ",telefono
    #print lineaGuiones
    #fecha vto. descripcion debe haber saldo
    #print " FECHA   DESCRIPCION"," "*28,"     "," "*7,"DEBE"," "*7,"HABER"," "*7,"SALDO"
    #print lineaGuiones

def procesaVentaTienePagos(idcliente,nrofactura,idventa,totales):
    #verifico si hay pagos realizados sobre la venta en el mismo momento de la compra
    listaPagos = ventasTienePagos(idventa)
    
    if listaPagos == None: return totales

    for pago in listaPagos:
        #fecha vto. descripcion debe haber saldo
        descripcion = ("Tck "+str(nrofactura)+" PAGO R "+pago['nrorecibo']+" "+pago['descrivalor'])[0:33]
        totalPago = pago['monto']
        totales[1] += Decimal(str(totalPago))
        totales[2] = totales[0] - totales[1]
        aux1 = "%12s" % ("%12.2f" % (totalPago))
        aux2 = "%12s" % ("%12.2f" % (totales[2]))
        #print lineaRenglon % (invertirFecha(pago['fecha']),descripcion,"","",aux1,aux2)
        grabaDetalle(idcliente,pago['fecha'],descripcion,"",Decimal("0.00"),totalPago)

    return totales #debe,haber,saldo

def procesaVtas_CtasCtes(idcliente,nrofactura,idventa,totales):
    #verifico si la venta se hizo en cuotas.
    #Esta informacion solo esta para mostrarse, no se utiliza para el calculo de saldos
    listaCtasCtes = vtas_CtasCtes(idventa)
    
    if listaCtasCtes == None: return totales

    #hay cuotas...!
    for cuota in listaCtasCtes:
        #se procesa una cuota
        totalCuota = cuota['montocuota']
        descripcion = ("Tck "+str(nrofactura)+" Cuota "+str(cuota['cuota'])+" "+cuota['descripcion']+" "+cuota['idformapagos'])[0:33]
        #no afecta al saldo porque ya se incluye alli el monto total de la factura en deudaUnCliente()
        #totales[0] += Decimal(str(totalCuota)) #debe
        #totales[2] = totales[0] - totales[1]
        aux1 = "$%s" % (totalCuota)
        #aux2 = "%12s" % ("%12.2f" % (totales[2]))
        #print lineaRenglon % (invertirFecha(cuota['vencimiento']),descripcion,aux1,"","","")
        grabaDetalle(idcliente,cuota['vencimiento'],descripcion,aux1,Decimal("0.00"),Decimal("0.00"))

    return totales

def procesaVtas_NC(idcliente,nrofactura,idventa,totales):
    listaNC = vtas_NC(idventa)
    if listaNC == None: return totales

    for nc in listaNC:
        descripcion = ("Tck "+str(nrofactura)+" NC "+nc['ptc']+" "+nc['descripcion'])[0:33]
        montoNC = nc['preciofinal']
        totales[1] += Decimal(str(montoNC)) #haber
        totales[2] = totales[0]-totales[1] #saldo
        aux1 = "%12.2f" % (montoNC)
        aux2 = "%12.2f" % (totales[2])
        #print lineaRenglon % (invertirFecha(nc['fecha']),descripcion,"","",aux1,aux2)
        grabaDetalle(idcliente,nc['fecha'],descripcion,"",Decimal("0.00"),montoNC)

    return totales

def procesaVtas_Valores(idcliente,totales):
    #aqui se muestran los valores recibidos y se calculan sus montos en la actualizacion del saldo
    #no se identifica que valor paga que cosa. Solo se considera el orden cronologico (la fecha del pago)
    listaValores = vtas_ValoresxCliente(idcliente)
    
    if listaValores == () or listaValores == None: return totales

    for valor in listaValores:
        detalle1 = ("RECIBO "+valor['idrecibo']+" "+valor['descripcion'])[0:33]
        detalle2 = valor['idformapago']
        montopagado = Decimal(str(valor['montopago']))
        totales[1] += montopagado #haber
        totales[2] = totales[0]-totales[1] #saldo
        aux1 = "%12.2f" % (montopagado)
        aux2 = "%12.2f" % (totales[2])
        #print lineaRenglon % (invertirFecha(valor['fecha']),detalle1,detalle2,"",aux1,aux2)
        grabaDetalle(idcliente,valor['fecha'],detalle1,detalle2,Decimal("0.00"),montopagado)
    
    return totales
    
def deudaUnCliente(idcliente,nombre,telefono):
    totales = [Decimal("0.00"),Decimal("0.00"),Decimal("0.00")] #debe,haber,saldo
    
    resultado = saldoMigracion(idcliente,nombre,telefono,totales)

    encabezado = resultado[0]
    totales    = resultado[1]

    listaVentas = ventas(idcliente)
    if listaVentas == None: return totales

    if encabezado:
        printEncabezado(idcliente,nombre,telefono)
        encabezado = False
    for venta in listaVentas:
        descripcion = str("Tck "+str(venta['nrofactura'])+" / "+venta['idventa'])[0:33]
        totalFactura = venta['totalfactura']
        totales[0] += Decimal(str(totalFactura)) #debe
        totales[2] = totales[0] - totales[1]
        aux1 = "%12s" % ("%12.2f" % (totalFactura))
        aux2 = "%12s" % ("%12.2f" % (totales[2]))
        #print lineaRenglon % (invertirFecha(venta['fecha']),descripcion,"",aux1,"",aux2)
        grabaDetalle(idcliente,venta['fecha'],descripcion,"",totalFactura,Decimal("0.00"))

        totales = procesaVentaTienePagos(idcliente,venta['nrofactura'],venta['idventa'],totales)
        totales = procesaVtas_CtasCtes(idcliente,venta['nrofactura'],venta['idventa'],totales)
        totales = procesaVtas_NC(idcliente,venta['nrofactura'],venta['idventa'],totales)

    totales = procesaVtas_Valores(idcliente,totales)

    return totales #debe,haber,saldo

# *****************************************************************************

if __name__ == '__main__':

    #python detalleCtaCte.py actualizar => este comando actualizara las tablas en la BD
    #python detalleCtaCte.py nrocliente => mostrara la informacion de 'nrocliente' especificado
    #python detalleCtaCte.py            => mostrara informacion de todos los clientes

    if len(sys.argv) < 2:
        listaClientes = listaClientes()
    else:
        if sys.argv[1] == "a":
            procesaArchivos()
            sys.exit()
        else:
            datos = datosCliente(sys.argv[1])
            if datos != None:
                listaClientes = [(sys.argv[1],datos[0],datos[1])]
            else:
                print "Cliente inexistente"
                sys.exit()

    os.system("cls")
    crearTabla()
    
    totalDebe  = Decimal("0.00")
    totalHaber = Decimal("0.00")
    totalSaldo = Decimal("0.00")
    for cliente in listaClientes:
        totales = deudaUnCliente(cliente[0],cliente[1],cliente[2])
        totalDebe  += totales[0]
        totalHaber += totales[1]
        totalSaldo += totales[2]

    aux1 = "$ %s" % totalDebe
    aux2 = "$ %s" % totalHaber
    aux3 = "$ %s" % totalSaldo
    #print "\n"
    #print lineaRenglon % ("TOTALES","","",aux1,aux2,aux3)

    miCursor.close()
    miBD.close()
    micursor.close()
